package util;

import context.*;

import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.media.*;
import javax.microedition.media.control.VideoControl;

import java.io.*;


// ***************************************************************************
// *** CLASS: MediePlayer
// ***************************************************************************
public class MediePlayer implements Debug.Constants
{ //private static final boolean DEBUG=true; // Overriding Debug.Constants.DEBUG
  private static final Command stopCommand=new Command("Stop",Command.STOP,1);
  private static final Command pauseCommand=new Command("Pause",Command.ITEM,1);
  private static final Command startCommand=new Command("Start",Command.ITEM,1);
  private Display display;
  private Displayable prev;
  private Player player=null;
  private PlayerForm playerForm=new PlayerForm(); // Note: inner class

  public MediePlayer(MIDlet midlet)
  { if(DEBUG) Debug.println("new MediePlayer()");
    this.display=Display.getDisplay(midlet);
  }
  
  public Player play(final InputStream in,String audioType)
  throws IOException,MediaException
  { stopAnyActivePlayer();
    if(DEBUG) Debug.println("MediePlayer.play: Create Player on Input Stream: "+in+", AudioType:"+audioType);
    player=Manager.createPlayer(in,audioType);
    new Thread("MediePlayer")
    { public void run()
      { try
        { //if(DEBUG) Debug.println("MediePlayer.play: Start Player on Input Stream: "+in+", AudioType:"+audioType);
          player.addPlayerListener(playerListener);

// 		player.setLoopCount(-1); // play indefinitely
		player.prefetch(); // prefetch
//		player.realize(); // realize

          player.realize();
          player.start();
        }
        catch(Exception e) { Debug.EXCEPTION("",e); }
      }
    }.start();
    return(player);
  }
  
  public void stopAnyActivePlayer()
  { if(player!=null)
    { if(LOG_PLAY_EVENT) Debug.log("MediePlayer.stopAnyActivePlayer","STOP ANY ACTIVE PLAYER");
      playerForm.deleteAll(); // clears the form of any previous controls
      player.close();
      player=null;
      Runtime runtime=Runtime.getRuntime();
      runtime.gc();
      if(LOG_PLAY_EVENT) Debug.log("MediePlayer.stopAnyActivePlayer"
              ,"FREE MEMORY="+runtime.freeMemory());
    }
  }
  
  PlayerListener playerListener=new PlayerListener()
  { public void playerUpdate(Player player,String event,Object eventData)
    { if(LOG_PLAY_EVENT) Debug.log("MediePlayer'playerListener.playerUpdate"
               ,"PLAYER EVENT: "+event+",data="+eventData);
	  if(event.equals(PlayerListener.STARTED) && new Long(0L).equals((Long)eventData))
	  {	// see if we can show a video control, depending on whether the media is a video or not
		VideoControl vc=null;
		if((vc=(VideoControl)player.getControl("VideoControl")) != null)
		{ Item videoDisp=(Item)vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE,null);
		  playerForm.append(videoDisp);
		}
		playerForm.show();
	  }    
      if(event.equals(PlayerListener.END_OF_MEDIA))
      { player.close();
        display.setCurrent(MediePlayer.this.prev);        
      }
      else if(event.equals(PlayerListener.CLOSED)) stopAnyActivePlayer();
    }
  };
  

  //******************************************************************
  //*** INNER CLASS: PlayerForm
  //******************************************************************
  private class PlayerForm extends Form
  {	public PlayerForm()
	{ super("MediePlayer");   
	  addCommand(stopCommand);
	  addCommand(pauseCommand);
	  setCommandListener(new CommandListener()
	  {	public void commandAction(Command command,Displayable disp)
	    { try
	      {	if(command==stopCommand)
	        { // if stopping the media play
//              player.close(); // close the player
              MediePlayer.this.stopAnyActivePlayer();
              // RYDD OPP !!!  TODO:
			  display.setCurrent(MediePlayer.this.prev);
			  PlayerForm.this.removeCommand(startCommand);
			  PlayerForm.this.addCommand(pauseCommand);
			} else if(command==pauseCommand)
			{ player.stop(); // pauses the media, note that it is called stop
			  PlayerForm.this.removeCommand(pauseCommand); // remove the pause command
			  PlayerForm.this.addCommand(startCommand); // add the start (restart) command
			} else if(command==startCommand)
			{ player.start(); // starts from where the last pause was called
			  PlayerForm.this.removeCommand(startCommand);
			  PlayerForm.this.addCommand(pauseCommand);
			}
		  } catch(Exception e) { Debug.EXCEPTION("",e); }
	    }  
	  });
	}
	
	public void show()
	{ MediePlayer.this.prev=display.getCurrent();
//	  Debug.println("VideoForm.show()");
	  Thread.yield(); // ?????
      display.setCurrent(this);		
	}
	
}
  
}
